Periodically sytnchronize Xen's wallclock time with NTP-synchronized time in domain0.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 26 Feb 2006 15:38:59 +0000 (16:38 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 26 Feb 2006 15:38:59 +0000 (16:38 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c

index 864bf17dafb68514d5cb8d9e457bfc2b8dca32aa..459a9d130bba60e24f797661017f8fe76919b997 100644 (file)
@@ -487,14 +487,45 @@ int do_settimeofday(struct timespec *tv)
 
 EXPORT_SYMBOL(do_settimeofday);
 
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+static void sync_xen_wallclock(unsigned long dummy);
+static DEFINE_TIMER(sync_xen_wallclock_timer, sync_xen_wallclock, 0, 0);
+static void sync_xen_wallclock(unsigned long dummy)
+{
+       time_t sec;
+       s64 nsec;
+       dom0_op_t op;
+
+       if (!ntp_synced() || independent_wallclock ||
+           !(xen_start_info->flags & SIF_INITDOMAIN))
+               return;
+
+       write_seqlock_irq(&xtime_lock);
+
+       sec  = xtime.tv_sec;
+       nsec = xtime.tv_nsec + ((jiffies - wall_jiffies) * (u64)NS_PER_TICK);
+       __normalize_time(&sec, &nsec);
+
+       op.cmd = DOM0_SETTIME;
+       op.u.settime.secs        = sec;
+       op.u.settime.nsecs       = nsec;
+       op.u.settime.system_time = processed_system_time;
+       HYPERVISOR_dom0_op(&op);
+
+       update_wallclock();
+
+       write_sequnlock_irq(&xtime_lock);
+
+       /* Once per minute. */
+       mod_timer(&sync_xen_wallclock_timer, jiffies + 60*HZ);
+}
+
 static int set_rtc_mmss(unsigned long nowtime)
 {
        int retval;
 
        WARN_ON(irqs_disabled());
 
-       if (!(xen_start_info->flags & SIF_INITDOMAIN))
+       if (independent_wallclock || !(xen_start_info->flags & SIF_INITDOMAIN))
                return 0;
 
        /* gets recalled with irq locally disabled */
@@ -507,12 +538,6 @@ static int set_rtc_mmss(unsigned long nowtime)
 
        return retval;
 }
-#else
-static int set_rtc_mmss(unsigned long nowtime)
-{
-       return 0;
-}
-#endif
 
 /* monotonic_clock(): returns # of nanoseconds passed since time_init()
  *             Note: This function is required to return accurate
@@ -768,6 +793,7 @@ static void sync_cmos_clock(unsigned long dummy)
 void notify_arch_cmos_timer(void)
 {
        mod_timer(&sync_cmos_timer, jiffies + 1);
+       mod_timer(&sync_xen_wallclock_timer, jiffies + 1);
 }
 
 static long clock_cmos_diff, sleep_start;